package cringer::search;

use JSON;

# search.pm
# provides search functionality for cringer using the Google AJAX Search API

our $VERSION = '2.0';

sub said{
 my $self = $_[0];
 my $args = $_[1];
 my $me = $self->{nick};
 
 unless($args->{body} =~ /^(lily|local|video|blogs|news|books|image|patent|doc|js|web)search: ?(.*)$/){ # if this isn't a search query, we skip it.
  return;
 }
 my @r; # set up the response array
 my $searchType = lc($1);
 my @q = ($2);
 
 my $searcher = qq~web~;
 if($searchType =~ /^(local|video|blogs|news|books|images|patent)$/){ # just in case we need something other than a web search
  $searcher = $1;
 } elsif($searchType eq "doc") {
  push(@q, qq~ site:code.google.com/apis inurl:documentation~);
 } elsif($searchType eq "js") {
  push(@q, qq~ site:developer.mozilla.org/en/~);
 } elsif($searchType eq "lily") {
  push(@q, qq~ site:lilypond.org/doc inurl:Documentation~);
 }

 
 $query = cringer::uriencode(join(' ', @q));
 my $url = qq~http://ajax.googleapis.com/ajax/services/search/$searcher?v=1.0&q=$query~;
 my $r = $self->{ua}->get($url);
 my $json;
 eval { $json = from_json($r->decoded_content); };
 if(($@ ne '') || defined($json->{responseData}->{error})){
  print qq~\n================\nSearch error:\n~ . $r->decoded_content . qq~\nError: $@\n================\n~;
  return qq~I'm sorry, but I encountered an error processing your query.~;
 }
 
 my $responseData = $json->{responseData};
 my $displayedResultCount = @{$responseData->{results}};
 my $erc = $responseData->{cursor}->{estimatedResultCount};
 push(@r, (($displayedResultCount) ? qq~Results 1-$displayedResultCount of estimated $erc~ : qq~I'm sorry, but there were no~) . qq~ $searchType results for "$q[0]"~ . (($displayedSearchResults) ? qq~:~ : qq~.~));
 my @results = defined($json->{responseData}->{results}) ? @{$json->{responseData}->{results}} : ();
 my $num = 1;
 foreach my $result (@results){
  my $sayMe = qq~$num. $result->{titleNoFormatting} ( ~; 
  if($searchType eq "lily") {$result->{content} =~ s/\<\/?[^>]+\>//g; $sayMe .= qq~$result->{content} ~; }
  if($searcher eq "local"){
   $sayMe .= qq~$result->{streetAddress} $result->{city}~;
   if(defined($result->{phoneNumbers})){
    $sayMe .= qq~ // $result->{phoneNumbers}->[0]->{number}~;
   }
  } elsif(defined($result->{postUrl})) {
   $sayMe .= $result->{postUrl};
  } elsif(defined($result->{unescapedUrl})){
   $sayMe .= $result->{unescapedUrl};
  } else {
   $sayMe .= $result->{url};
  }
  $sayMe .= qq~ )~;
  push(@r, $sayMe);
  $num++;
 }
 if((@results == 4) && ($erc > 4) && (cringer::gtg($responseData->{cursor}->{moreResultsUrl}))){
  push (@r, qq~For more results: $responseData->{cursor}->{moreResultsUrl}~);
 }
 return (@r > 0) ? @r : undef;
}
sub commandList{ # a simple help routine to return a list of the commands we'll respond to
 my @commands;
 foreach my $c (qw~local video blogs news books image patent doc js web~){
  push(@commands, $c.qq~search: [query]~);
 }
 return join(' | ', @commands);
}
return 1;
